/**
 * 响应式相关组合式函数
 */
import { ref, computed, onMounted, onUnmounted } from "vue";
import { BREAKPOINTS } from "@/constants";
import { throttle } from "@/utils";

type DeviceType = "mobile" | "tablet" | "desktop";
type BreakpointKey = "xs" | "sm" | "md" | "lg" | "xl" | "xxl";

export function useResponsive() {
  const windowWidth = ref(0);
  const windowHeight = ref(0);

  // 设备类型
  const deviceType = computed<DeviceType>(() => {
    if (windowWidth.value < BREAKPOINTS.MD) {
      return "mobile";
    } else if (windowWidth.value < BREAKPOINTS.LG) {
      return "tablet";
    } else {
      return "desktop";
    }
  });

  // 是否为移动设备
  const isMobile = computed(() => deviceType.value === "mobile");

  // 是否为平板设备
  const isTablet = computed(() => deviceType.value === "tablet");

  // 是否为桌面设备
  const isDesktop = computed(() => deviceType.value === "desktop");

  // 断点检查
  const breakpoints = computed(() => ({
    xs: windowWidth.value >= BREAKPOINTS.XS,
    sm: windowWidth.value >= BREAKPOINTS.SM,
    md: windowWidth.value >= BREAKPOINTS.MD,
    lg: windowWidth.value >= BREAKPOINTS.LG,
    xl: windowWidth.value >= BREAKPOINTS.XL,
    xxl: windowWidth.value >= BREAKPOINTS.XXL,
  }));

  // 当前断点
  const currentBreakpoint = computed<BreakpointKey>(() => {
    if (windowWidth.value >= BREAKPOINTS.XXL) return "xxl";
    if (windowWidth.value >= BREAKPOINTS.XL) return "xl";
    if (windowWidth.value >= BREAKPOINTS.LG) return "lg";
    if (windowWidth.value >= BREAKPOINTS.MD) return "md";
    if (windowWidth.value >= BREAKPOINTS.SM) return "sm";
    return "xs";
  });

  // 屏幕方向
  const orientation = computed(() => {
    return windowWidth.value > windowHeight.value ? "landscape" : "portrait";
  });

  // 是否为横屏
  const isLandscape = computed(() => orientation.value === "landscape");

  // 是否为竖屏
  const isPortrait = computed(() => orientation.value === "portrait");

  // 更新窗口尺寸
  const updateWindowSize = throttle(() => {
    windowWidth.value = window.innerWidth;
    windowHeight.value = window.innerHeight;
  }, 100);

  // 检查是否匹配断点
  const matchBreakpoint = (breakpoint: BreakpointKey | BreakpointKey[]) => {
    if (Array.isArray(breakpoint)) {
      return breakpoint.includes(currentBreakpoint.value);
    }
    return currentBreakpoint.value === breakpoint;
  };

  // 检查是否大于等于指定断点
  const greaterThanOrEqual = (breakpoint: BreakpointKey) => {
    const breakpointOrder: BreakpointKey[] = [
      "xs",
      "sm",
      "md",
      "lg",
      "xl",
      "xxl",
    ];
    const currentIndex = breakpointOrder.indexOf(currentBreakpoint.value);
    const targetIndex = breakpointOrder.indexOf(breakpoint);
    return currentIndex >= targetIndex;
  };

  // 检查是否小于等于指定断点
  const lessThanOrEqual = (breakpoint: BreakpointKey) => {
    const breakpointOrder: BreakpointKey[] = [
      "xs",
      "sm",
      "md",
      "lg",
      "xl",
      "xxl",
    ];
    const currentIndex = breakpointOrder.indexOf(currentBreakpoint.value);
    const targetIndex = breakpointOrder.indexOf(breakpoint);
    return currentIndex <= targetIndex;
  };

  // 获取响应式值
  const getResponsiveValue = <T>(
    values: Partial<Record<BreakpointKey, T>>,
    defaultValue: T,
  ): T => {
    const breakpointOrder: BreakpointKey[] = [
      "xxl",
      "xl",
      "lg",
      "md",
      "sm",
      "xs",
    ];

    for (const bp of breakpointOrder) {
      if (greaterThanOrEqual(bp) && values[bp] !== undefined) {
        return values[bp]!;
      }
    }

    return defaultValue;
  };

  // 获取网格列数
  const getGridCols = (
    cols: Partial<Record<BreakpointKey, number>>,
    defaultCols = 1,
  ): number => {
    return getResponsiveValue(cols, defaultCols);
  };

  // 获取间距大小
  const getSpacing = (
    spacing: Partial<Record<BreakpointKey, number>>,
    defaultSpacing = 16,
  ): number => {
    return getResponsiveValue(spacing, defaultSpacing);
  };

  // 初始化
  const init = () => {
    updateWindowSize();
    window.addEventListener("resize", updateWindowSize);
    window.addEventListener("orientationchange", updateWindowSize);
  };

  // 清理
  const cleanup = () => {
    window.removeEventListener("resize", updateWindowSize);
    window.removeEventListener("orientationchange", updateWindowSize);
  };

  onMounted(() => {
    init();
  });

  onUnmounted(() => {
    cleanup();
  });

  return {
    // 状态
    windowWidth: readonly(windowWidth),
    windowHeight: readonly(windowHeight),

    // 计算属性
    deviceType,
    isMobile,
    isTablet,
    isDesktop,
    breakpoints,
    currentBreakpoint,
    orientation,
    isLandscape,
    isPortrait,

    // 方法
    matchBreakpoint,
    greaterThanOrEqual,
    lessThanOrEqual,
    getResponsiveValue,
    getGridCols,
    getSpacing,
    updateWindowSize,
  };
}

// 全局响应式管理
const globalResponsive = useResponsive();

export const useGlobalResponsive = () => globalResponsive;
